/******************************************************************************
*	device/hub.h
*	 by Alex Chadwick
*
*	A light weight implementation of the USB protocol stack fit for a simple
*	driver.
*
*	device/hub.h contains definitions relating to the USB hub device.
******************************************************************************/
#ifndef _DEVICE_HUB_H
#define _DEVICE_HUB_H

#include <usbd/descriptors.h>
#include <usbd/device.h>
#include <types.h>

//------------------------------------------------------------------------------
// The hub descriptor information.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.23.2.1
typedef
	enum HubPortControl {
		Global     = 0,
		Individual = 1,
	}
HubPortControl;

typedef
	struct HdAttributes {
		HubPortControl PowerSwitchingMode    : 2;  // @0
		bool           Compound              : 1;  // @2
		HubPortControl OverCurrentProtection : 2;  // @3
		unsigned       ThinkTime             : 2;  // @5 (in +1*8FS units)
		bool           Indicators            : 1;  // @7
		unsigned       _reserved8_15         : 8;  // @8
	}
HdAttributes;

typedef
	struct HubDescriptor {
		u8             DescriptorLength;    // +0x0
		DescriptorTYPE DescriptorType : 8;  // +0x1
		u8             PortCount;           // +0x2
		HdAttributes   Attributes;          // +0x3
		u8             PowerGoodDelay;      // +0x5
		u8             MaximumHubPower;     // +0x6
		// Data is N bytes describing port detatchability,
		//  followed by n bytes for compatiblity.  Where n = roundup(ports / 8)
		u8             Data[];              // +0x7
	} STRUCTPACK
HubDescriptor;

//------------------------------------------------------------------------------
// Encapsulates the current status of a hub.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.24.2.6
typedef
	struct HubStatus {
		bool     LocalPower    :  1;  // @0
		bool     OverCurrent   :  1;  // @1
		unsigned _reserved2_15 : 14;  // @2
	}
HubStatus;

//------------------------------------------------------------------------------
// Encapsulates the change in current status of a hub.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.24.2.6
typedef
	struct HubStatusChange {
		bool     LocalPowerChanged  :  1;  // @0
		bool     OverCurrentChanged :  1;  // @1
		unsigned _reserved2_15      : 14;  // @2
	}
HubStatusChange;

//------------------------------------------------------------------------------
// Encapsulates the full status of a hub.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.24.2.6
typedef
	struct HubFullStatus {
		HubStatus       Status;
		HubStatusChange Change;
	}
HubFullStatus;

//------------------------------------------------------------------------------
// Encapsulates the current status of a hub port.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.24.2.7.1
typedef
	struct HubPortStatus {
		bool      Connected         : 1;  // @0
		bool      Enabled           : 1;  // @1
		bool      Suspended         : 1;  // @2
		bool      OverCurrent       : 1;  // @3
		bool      Reset             : 1;  // @4
		unsigned _reserved5_7       : 3;  // @5
		bool     Power              : 1;  // @8
		bool     LowSpeedAttatched  : 1;  // @9
		bool     HighSpeedAttatched : 1;  // @10
		bool     TestMode           : 1;  // @11
		bool     IndicatorControl   : 1;  // @12
		unsigned _reserved13_15     : 3;  // @13
	}
HubPortStatus;

//------------------------------------------------------------------------------
// Encapsulates the change in current status of a hub port.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.24.2.7.2
typedef
	struct HubPortStatusChange {
		bool      ConnectedChanged   :  1;  // @0
		bool      EnabledChanged     :  1;  // @1
		bool      SuspendedChanged   :  1;  // @2
		bool      OverCurrentChanged :  1;  // @3
		bool      ResetChanged       :  1;  // @4
		unsigned _reserved5_15       : 11;  // @5
	}
HubPortStatusChange;

//------------------------------------------------------------------------------
// Encapsulates the full status of a hub port.
// Defined in "USB Sepcification, Rev 2.0, 27/Apr/2000" section 11.24.2.7
typedef
	struct HubPortFullStatus {
		HubPortStatus       Status;
		HubPortStatusChange Change;
	}
HubPortFullStatus;

//------------------------------------------------------------------------------
// The feautres of a hub port that can be altered.
typedef
	enum HubPortFeature {
		FeatureConnection        =  0,
		FeatureEnable            =  1,
		FeatureSuspend           =  2,
		FeatureOverCurrent       =  3,
		FeatureReset             =  4,
		FeaturePower             =  8,
		FeatureLowSpeed          =  9,
		FeatureHighSpeed         = 10,
		FeatureConnectionChange  = 16,
		FeatureEnableChange      = 17,
		FeatureSuspendChange     = 18,
		FeatureOverCurrentChange = 19,
		FeatureResetChange       = 20,
	}
HubPortFeature;

//------------------------------------------------------------------------------
// The DeviceDriver field in UsbDriverDataHeader for hubs.
#define DeviceDriverHub  (0x48554230)

//------------------------------------------------------------------------------
// Hub specific data - The contents of the driver data field for hubs.
typedef
	struct HubDevice {
		UsbDriverDataHeader Header;
		HubFullStatus       Status;
		HubDescriptor       *Descriptor;
		u32                 MaxChildren;
		HubPortFullStatus   PortStatus[MaxChildrenPerDevice];
		UsbDevice           *Children[MaxChildrenPerDevice];
	}
HubDevice;

//------------------------------------------------------------------------------
// The feautres of a hub that can be altered.
typedef
	enum HubFeature {
		FeatureHubPower       = 0,
		FeatureHubOverCurrent = 1,
	}
HubFeature;

//------------------------------------------------------------------------------
Result  HubAttach (UsbDevice *device, u32 interfaceNumber) ;
Result  HubPortReset (UsbDevice *device, u8 port) ;
Result  HubCheckConnection (UsbDevice *device, u8 port) ;

/**
	\brief Checks all hubs for new devices.

	Recursively checks the hub tree for new devices being attached, and for old
	devices being removed.
*/
void  HubRecursiveCheck (UsbDevice *device) ;

#endif // _DEVICE_HUB_H
